package com.springmvc.handlers;

import java.io.IOException;
import java.io.Writer;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.springmvc.entities.User;

@Controller
@RequestMapping("/springmvc")
public class SpringMVCTest {

	private static final String SUCCESS="success";
	
	/**
	 * 目标方法的返回值可以是 ModelAndView 类型。 
	 * 其中可以包含视图和模型信息
	 * SpringMVC 会把 ModelAndView 的 model 中数据放入到 request 域对象中. 
	 * @return
	 */
	@RequestMapping("/testModelAndView")
	public ModelAndView testModelAndView() {
		String viewName=SUCCESS;
		ModelAndView modelAndView=new ModelAndView(viewName);
		//添加模型数据到ModelAndView中
		modelAndView.addObject("time", new Date());
		return modelAndView;
	}
	
	/**
	 * 可以使用Servlet原生的API作为目标方法的参数
	 * @throws IOException 
	 */
	@RequestMapping("/testServletAPI")
	public void testServletAPI(HttpServletRequest request, HttpServletResponse response,
			Writer out) throws IOException {
		System.out.println("testServletAPI："+request+","+response);
		out.write("hello springmvc!");//此处out对象是调用了responce.getWriter方法获得的
//		return SUCCESS;
	}
	
	@RequestMapping("/testPOJO")
	public String testPOJO(User user) {
		System.out.println("testPOJO："+user);
		return SUCCESS;
	}
	
	/**
	 * 了解：
	 * @CookieValue：映射一个Cookie值，属性同 @RequestParam
	 */
	@RequestMapping(value="/testCookieValue")
	public String testCookieValue(@CookieValue(value="JSESSIONID") String cv) {
		
		System.out.println("testCookieValue：JSESSIONID="+cv);
		return SUCCESS;
	}
	
	/**
	 * 了解：
	 * 映射请求头
	 */
	@RequestMapping(value="/testRequestHeader")
	public String testRequestHeader(@RequestHeader(value="Accept-Language") String al) {
		
		System.out.println("testRequestHeader：Accept_Language="+al);
		return SUCCESS;
	}
	
	/**
	 * @RequestParam 来映射请求参数. 
	 * value 值即请求参数的参数名 
	 * required 该参数是否必须. 默认为 true
	 * defaultValue 请求参数的默认值
	 */
	@RequestMapping(value="/testRequestParam")
	public String testRequestParam(@RequestParam(value="username") String un,
			@RequestParam(value="age" , required=false, defaultValue="0") Integer age) {
		
		System.out.println("testRequestParam：username="+un+",age="+age);
		return SUCCESS;
	}
	
	/**
	 * Rest 风格的 URL. 
	 * 以 CRUD 为例: 
	 * 新增: /order POST 
	 * 修改: /order/1 PUT     update?id=1 
	 * 获取: /order/1 GET     get?id=1 
	 * 删除: /order/1 DELETE  delete?id=1
	 * 
	 * 如何发送 PUT 请求和 DELETE 请求呢 ? 
	 * 1. 需要配置 HiddenHttpMethodFilter 
	 * 2. 需要发送 POST 请求
	 * 3. 需要在发送 POST 请求时携带一个 name="_method" 的隐藏域, 值为 DELETE 或 PUT
	 * 
	 * 在 SpringMVC 的目标方法中如何得到 id 呢? 使用 @PathVariable 注解
	 * 
	 */
	@RequestMapping(value="/testREST/{id}" , method=RequestMethod.GET)
	public String testREST(@PathVariable("id") Integer id) {
		System.out.println("testREST GET : "+id);
		return SUCCESS;
	}
	
	@RequestMapping(value="/testREST" , method=RequestMethod.POST)
	public String testREST() {
		System.out.println("testREST POST");
		return SUCCESS;
	}
	
	@RequestMapping(value="/testREST/{id}" , method=RequestMethod.DELETE)
	public String testRESTdelete(@PathVariable("id") Integer id) {
		System.out.println("testREST DELETE："+id);
		return SUCCESS;
	}
	
	@RequestMapping(value="/testREST/{id}" , method=RequestMethod.PUT)
	public String testRESTput(@PathVariable("id") Integer id) {
		System.out.println("testREST PUT："+id);
		return SUCCESS;
	}
}
